package com.winning.ds.common.config.multiDatasource;

import java.lang.reflect.Method;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/**
 * 自定义注解@DS + AOP的方式实现数据源动态切换。
 */
@Aspect
@Component
@Slf4j
//@ConditionalOnProperty(prefix = "com.winning.dqmt", name = "multiDatasourceOpen", havingValue = "true")
public class DynamicDataSourceAspect implements Ordered {

   /* @Before("@annotation(DataSource)")
    public void beforeSwitchDS(JoinPoint point) {
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();
        //获得访问的方法名
        String methodName = point.getSignature().getName();
        //得到方法的参数的类型
        Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();
        String dataSource = DataSourceContextHolder.DEFAULT_DS;
        try {
            // 得到访问的方法对象
            Method method = className.getMethod(methodName, argClass);
            // 判断是否存在@DS注解
            if (method.isAnnotationPresent(DataSource.class)) {
                DataSource annotation = method.getAnnotation(DataSource.class);
                // 取出注解中的数据源名
                dataSource = annotation.value();
            }
        } catch (Exception e) {
            log.error("数据源切换异常:", e);
        }
        // 切换数据源
        DataSourceContextHolder.setDB(dataSource);
        log.debug("设置数据源为：" + dataSource);
    }

    @After("@annotation(DataSource)")
    public void afterSwitchDS() {
        DataSourceContextHolder.clearDB();
        log.debug("清空数据源信息！");
    }

    @Override
    public int getOrder() {
        return 1;
    }*/



    public DynamicDataSourceAspect() {
        log.info("多数据源初始化 AOP ");
    }

    @Pointcut(value = "@annotation(com.winning.ds.common.config.multiDatasource.DataSource)")
    private void cut() {
    }

    @Around("cut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Signature signature = point.getSignature();
        MethodSignature methodSignature;
        if (!(signature instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        methodSignature = (MethodSignature) signature;
        //获取当点方法的注解
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        DataSource annotation = currentMethod.getAnnotation(DataSource.class);

        if (annotation != null) {
            DataSourceContextHolder.setDB(annotation.value());
            log.debug("设置数据源为：" + annotation.value());
        } else {
            DataSourceContextHolder.setDB("store");
            log.debug("设置数据源为：默认  -->  store");
        }
        try {
            return point.proceed();
        } finally {
            log.debug("清空数据源信息！");
            DataSourceContextHolder.clearDB();
        }

    }


    @Override
    public int getOrder() {
        return 2;
    }
}
